#ifndef _JJTSTATE_H_
#define _JJTSTATE_H_
#include <QList>
#include "SimpleNode.h"
class PythonTreeBuilder;
class PythonGrammar;

class JJTState
{
public:
    JJTState();
    virtual ~JJTState();

    SimpleNodePtr getLastOpened();

    //Determines whether the current node was actually closed and
    //pushed.  This should only be called in the final user action of a
    //node scope.
    virtual bool nodeCreated();

    //Call this to reinitialize the node stack.  It is called
    //automatically by the parser's ReInit() method.
    virtual void reset();

    //Returns the root node of the AST.  It only makes sense to call
    //this after a successful parse.
    virtual SimpleNodePtr rootNode();

    //Pushes a node on to the stack.
    virtual void pushNode(const SimpleNodePtr& n);

    //Returns the node on the top of the stack, and remove it from the
    //stack.
    virtual SimpleNodePtr popNode();
    template<class T>
    QSharedPointer<T> popNode(){
        return popNode().dynamicCast<T>();
    }

    //Returns the node currently on the top of the stack.
    virtual SimpleNodePtr peekNode();
    template<class T>
    QSharedPointer<T> peekNode(){
        return peekNode().dynamicCast<T>();
    }

    //virtual SimpleNodePtr peekNode(int i);

    //Returns the number of children on the stack in the current node
    //scope.
    virtual int nodeArity();

    virtual void clearNodeScope(const SimpleNodePtr& n);


    virtual void openNodeScope(const SimpleNodePtr& n);


    //A definite node is constructed from a specified number of
    //children.  That number of nodes are popped from the stack and
    //made the children of the definite node.  Then the definite node
    //is pushed on to the stack.
    virtual void closeNodeScope(const SimpleNodePtr& n, int num);


    //A conditional node is constructed if its condition is true.  All
    //the nodes that have been pushed since the node was opened are
    //made children of the conditional node, which is then pushed
    //on to the stack.  If the condition is false the node is not
    //constructed and they are left on the stack. */
    virtual void closeNodeScope(const SimpleNodePtr& n, bool condition);

    bool lastIsNewScope();
    void setGrammar(PythonGrammar* grammar);
    PythonTreeBuilder* builder();
    PythonGrammar* grammar();
private:
    void pushNode(const SimpleNodePtr& n, const SimpleNodePtr& created, int line, int col);
    void clearMark();
protected:
    QList<int> _marks;
    QList<int> _lines;
    QList<int> _columns;
    QList<SimpleNodePtr> _nodes;

    int _sp;
    int _mk;
    bool _nodeCreated;
    int _debugLevel;

    PythonTreeBuilder* _builder;
    PythonGrammar* _grammar;
};

#endif
